package strategy

import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"

	"monitor.ilin.cc/internal/pkg/strategy"
	"monitor.ilin.cc/internal/services/alert"
)

type Manager struct {
	strategies []strategy.Strategy
	alerter    alert.Service
	mu         sync.RWMutex
	// 用于发送告警的channel
	alertCh chan *alertMessage
	// 控制并发数
	workerLimit chan struct{}
}

type alertMessage struct {
	level   string
	title   string
	content string
}

func NewManager(alerter alert.Service) *Manager {
	m := &Manager{
		strategies:  make([]strategy.Strategy, 0),
		alerter:     alerter,
		alertCh:     make(chan *alertMessage, 100), // 缓冲区大小根据实际情况调整
		workerLimit: make(chan struct{}, 10),       // 最多10个并发
	}

	// 启动告警处理goroutine
	go m.handleAlerts()

	return m
}

func (m *Manager) AddStrategy(s strategy.Strategy) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.strategies = append(m.strategies, s)
}

func (m *Manager) OnTick(symbol string, price float64, timestamp time.Time) {
	// 添加基本验证
	if symbol == "" || price <= 0 {
		log.Printf("无效的数据: symbol=%s, price=%.2f", symbol, price)
		return
	}

	// 创建带超时的context
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	m.mu.RLock()
	strategies := m.strategies
	m.mu.RUnlock()

	var wg sync.WaitGroup

	for _, s := range strategies {
		// 跳过不相关的交易对
		if s.GetSymbol() != symbol {
			continue
		}

		wg.Add(1)
		go func(s strategy.Strategy) {
			defer wg.Done()

			// 获取worker令牌
			select {
			case m.workerLimit <- struct{}{}:
				defer func() { <-m.workerLimit }()
			case <-ctx.Done():
				log.Printf("策略执行超时取消: %v", ctx.Err())
				return
			}

			// 添加panic恢复
			defer func() {
				if r := recover(); r != nil {
					log.Printf("策略执行panic: %v", r)
				}
			}()

			signal, err := s.Update(price, timestamp)
			if err != nil {
				//log.Printf("策略更新失败 [%s]: %v", symbol, err)
				return
			}

			if signal != nil {
				// 添加更多信号验证
				if signal.Price <= 0 || signal.Timestamp.IsZero() {
					log.Printf("无效的信号数据 [%s]: price=%.2f, time=%v",
						symbol, signal.Price, signal.Timestamp)
					return
				}

				// 根据信号类型选择不同的emoji和动作描述
				var actionEmoji, actionText string
				if signal.Type == strategy.BuySignal {
					actionEmoji = "📈"
					actionText = "买入"
				} else {
					actionEmoji = "📉"
					actionText = "卖出"
				}

				// 生成通知消息
				msg := fmt.Sprintf("%s %s信号提醒\n\n"+
					"🔄 交易对: %s\n"+
					"📅 时间: %s\n"+
					"💰 价格: %.2f\n"+
					"⚡ 操作: %s\n"+
					"📝 信号: %s",
					actionEmoji,
					actionText,
					symbol,
					signal.Timestamp.Format("2006-01-02 15:04:05"),
					signal.Price,
					actionText,
					signal.Reason,
				)

				// 异步发送告警
				select {
				case m.alertCh <- &alertMessage{
					level:   "INFO",
					title:   "交易信号",
					content: msg,
				}:
				default:
					log.Printf("告警channel已满,丢弃消息")
				}

				// 同时在控制台输出
				log.Printf("[交易信号] 交易对: %s, 时间: %v, 价格: %.2f, 操作: %s, 原因: %s",
					symbol,
					signal.Timestamp.Format("2006-01-02 15:04:05"),
					signal.Price,
					actionText,
					signal.Reason,
				)
			}
		}(s)
	}

	// 等待所有策略执行完成
	wg.Wait()
}

// 处理告警消息的goroutine
func (m *Manager) handleAlerts() {
	for msg := range m.alertCh {
		if err := m.alerter.SendAlert(msg.level, msg.title, msg.content); err != nil {
			log.Printf("发送告警失败: %v", err)
		}
	}
}
